package cn.tftech.hudchartssw;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.util.TypedValue;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.github.abel533.echarts.Grid;
import com.github.abel533.echarts.Label;
import com.github.abel533.echarts.LabelLine;
import com.github.abel533.echarts.Legend;
import com.github.abel533.echarts.axis.AxisLine;
import com.github.abel533.echarts.axis.CategoryAxis;
import com.github.abel533.echarts.axis.ValueAxis;
import com.github.abel533.echarts.json.GsonOption;
import com.github.abel533.echarts.option.NoDataLoadingOption;
import com.github.abel533.echarts.series.Bar;
import com.github.abel533.echarts.series.Effect;
import com.github.abel533.echarts.series.Pie;
import com.github.abel533.echarts.series.Series;
import com.github.abel533.echarts.style.ItemStyle;
import com.github.abel533.echarts.style.LineStyle;
import com.github.abel533.echarts.style.TextStyle;
import com.github.abel533.echarts.style.itemstyle.Emphasis;
import com.github.abel533.echarts.style.itemstyle.Normal;
import com.tbruyelle.rxpermissions2.RxPermissions;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import cn.tftech.hudchartssw.request.ConstantCommon;
import cn.tftech.hudchartssw.request.HudBean;
import cn.tftech.hudchartssw.request.LocalDataSource;
import cn.tftech.hudchartssw.request.RxUtils;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import me.jessyan.autosize.AutoSizeCompat;

import static com.github.abel533.echarts.code.LoadingEffect.whirling;
import static com.github.abel533.echarts.code.Orient.horizontal;

public class MainActivity extends Activity {

    private EChartView listOneCenter, listOneBottom;
    private EChartView listTwoTop, listTwoBottom;
    private EChartView listThreeNo2, listThreeNo4;
    private TextStyle titleStyle, textStyle;
    private List<HudBean> data;

    private static final String FLAG_LIST_ONE_TOP1 = "001";
    private static final String FLAG_LIST_ONE_TOP2 = "002";
    private static final String FLAG_LIST_ONE_CENTER = "003";
    private static final String FLAG_LIST_ONE_BOTTOM = "004";
    private static final String FLAG_LIST_TWO_TOP = "005";
    private static final String FLAG_LIST_TWO_BOTTOM = "006";
    private static final String FLAG_LIST_THREE_NO1 = "007";
    private static final String FLAG_LIST_THREE_NO2 = "008";
    private static final String FLAG_LIST_THREE_NO3 = "009";
    private static final String FLAG_LIST_THREE_NO4 = "010";

    private static final String[] COLORS = new String[]{"#7bd6a6", "#3b75df", "#fbdb6d", "#5afffd"};

    @Override
    public Resources getResources() {
        AutoSizeCompat.autoConvertDensityOfGlobal((super.getResources()));
        return super.getResources();
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    @SuppressLint("CheckResult")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 全屏设置
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        textStyle = new TextStyle();
        textStyle.setFontSize(8);
        titleStyle = new TextStyle();
        titleStyle.setFontSize(12);
        RxPermissions rxPermissions = new RxPermissions(this);
        rxPermissions.request(Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE).subscribe(aBoolean -> {
            if (!aBoolean) {
                System.exit(0);
            } else {
                getHudBeans();
            }
        });


    }

    private void getHudBeans() {
        LocalDataSource.getInstance().getHudData().compose(
                RxUtils.netWork()).subscribe(new Observer<List<HudBean>>() {
            @Override
            public void onSubscribe(Disposable d) {
            }

            @Override
            public void onNext(List<HudBean> hudBeans) {
                data = hudBeans;
                displayViewListOneTop();
                displayViewListOneCenter();
                displayViewListOneBottom();
                displayViewListTwoTop();
                displayViewListTwoBottom();
                displayViewListThreeNo1();
                displayViewListThreeNo2();
                displayViewListThreeNo3();
                displayViewListThreeNo4();
            }

            @Override
            public void onError(Throwable e) {
            }

            @Override
            public void onComplete() {
            }
        });
    }

    /**
     * 显示第一列上部分View
     */
    @SuppressLint("SetTextI18n")
    private void displayViewListOneTop() {
        LinearLayout listOneTop1 = findViewById(R.id.list_one_top1);
        RelativeLayout listOneTop1Text = findViewById(R.id.list_one_top1_text);
        LinearLayout listOneTop2 = findViewById(R.id.list_one_top2);
        RelativeLayout listOneTop2Text = findViewById(R.id.list_one_top2_text);
        makeLineCharts(FLAG_LIST_ONE_TOP1, listOneTop1, listOneTop1Text);
        makeLineCharts(FLAG_LIST_ONE_TOP2, listOneTop2, listOneTop2Text);
    }

    /**
     * 显示第一列中间部分View
     */
    private void displayViewListOneCenter() {
        listOneCenter = findViewById(R.id.list_one_center);
        listOneCenter.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                listOneCenter.refreshEChartsWithOption(FLAG_LIST_ONE_CENTER,
                        getBarOption(FLAG_LIST_ONE_CENTER, null));
            }
        });
    }

    /**
     * 显示第一列下部分View
     */
    private void displayViewListOneBottom() {
        listOneBottom = findViewById(R.id.list_one_bottom);
        listOneBottom.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                listOneBottom.refreshEChartsWithOption(FLAG_LIST_ONE_BOTTOM,
                        getPieOption(FLAG_LIST_ONE_BOTTOM)
                );
            }
        });
    }

    /**
     * 显示第二列顶部View
     */
    private void displayViewListTwoTop() {
        listTwoTop = findViewById(R.id.list_two_top);
        listTwoTop.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                listTwoTop.refreshEChartsWithOption(FLAG_LIST_TWO_TOP,
                        getPieOption(FLAG_LIST_TWO_TOP)
                );
            }
        });
    }

    /**
     * 显示第二列底部View
     */
    @SuppressLint("SetTextI18n")
    private void displayViewListTwoBottom() {
        TextView listTwoBottomMsg = findViewById(R.id.list_two_bottom_msg);
        listTwoBottom = findViewById(R.id.list_two_bottom);
        listTwoBottom.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                listTwoBottom.refreshEChartsWithOption(FLAG_LIST_TWO_BOTTOM,
                        getBarOption(FLAG_LIST_TWO_BOTTOM, listTwoBottomMsg)
                );
            }
        });
    }

    /**
     * 显示第三列第一部分View
     */
    private void displayViewListThreeNo1() {
        LinearLayout listTreeNo1 = findViewById(R.id.list_three_no1);
        RelativeLayout listTreeNo1Text = findViewById(R.id.list_three_no1_text);
        makeLineCharts(FLAG_LIST_THREE_NO1, listTreeNo1, listTreeNo1Text);
    }

    /**
     * 显示第三列第二部分View
     */
    @SuppressLint("SetTextI18n")
    private void displayViewListThreeNo2() {
        TextView listThreeNo2Msg = findViewById(R.id.list_three_no2_msg);
        listThreeNo2 = findViewById(R.id.list_three_no2);
        listThreeNo2.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                listThreeNo2.refreshEChartsWithOption(FLAG_LIST_THREE_NO2,
                        getBarOption(FLAG_LIST_THREE_NO2, listThreeNo2Msg));
            }
        });
    }

    /**
     * 显示第三列第三部分View
     */
    private void displayViewListThreeNo3() {
        LinearLayout listTreeNo3 = findViewById(R.id.list_three_no3);
        RelativeLayout listTreeNo3Text = findViewById(R.id.list_three_no3_text);
        makeLineCharts(FLAG_LIST_THREE_NO3, listTreeNo3, listTreeNo3Text);
    }

    /**
     * 显示第三列第四部分View
     */
    @SuppressLint("SetTextI18n")
    private void displayViewListThreeNo4() {
        TextView listThreeNo4Msg = findViewById(R.id.list_three_no4_msg);
        listThreeNo4 = findViewById(R.id.list_three_no4);
        listThreeNo4.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                listThreeNo4.refreshEChartsWithOption(FLAG_LIST_THREE_NO4,
                        getBarOption(FLAG_LIST_THREE_NO4, listThreeNo4Msg));
            }
        });
    }

    /**
     * 初始化条状图
     *
     * @param flag      flag
     * @param chartView chartView
     * @param chartTips chartTipsView
     */
    @SuppressLint("SetTextI18n")
    private void makeLineCharts(String flag, LinearLayout chartView, RelativeLayout chartTips) {
        List<HudBean> chartData = new ArrayList<>();
        for (HudBean hb : data) {
            if (flag.equals(hb.getKeyId())) {
                chartData.add(hb);
            }
        }
        for (int i = 0; i < chartData.size(); i++) {
            TextView chart = new TextView(this);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT,
                    Integer.parseInt(chartData.get(i).getKeyValue()));
            chart.setLayoutParams(layoutParams);
            chart.setBackgroundColor(Color.parseColor(COLORS[i]));
            chartView.addView(chart);

            TextView tips = new TextView(this);
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            switch (i) {
                case 0:
                    if (chartData.size() == 1) {
                        lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
                    } else {
                        lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
                    }
                    break;
                case 1:
                    if (i == chartData.size() - 1) {
                        lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                    } else {
                        lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
                    }
                    break;
                case 2:
                    lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                    break;
            }
            tips.setLayoutParams(lp);
            tips.setText(chartData.get(i).getKeyName() + chartData.get(i).getKeyValue() + "人");
            tips.setTextSize(TypedValue.COMPLEX_UNIT_SP, 8);
            tips.setTextColor(Color.parseColor(COLORS[i]));
            tips.setMaxLines(1);
            chartTips.addView(tips);
        }
    }

    @SuppressLint("SetTextI18n")
    private GsonOption getBarOption(String flag, TextView msg) {
        GsonOption option = new GsonOption();
        NoDataLoadingOption noDataLoadingOption = new NoDataLoadingOption();
        Effect effect = new Effect();
        effect.show(true);
//        effect.color("#465461");
//        noDataLoadingOption.effect(effect);
        noDataLoadingOption.text("加载中");
        noDataLoadingOption.textStyle(textStyle);
        noDataLoadingOption.effect(whirling);
        option.noDataLoadingOption(noDataLoadingOption);

        option.itemStyle().normal().textStyle(textStyle);
        option.legend().x("0").y("0").itemWidth(10).itemHeight(6);
        //option.tooltip().trigger(Trigger.axis);
        option.calculable(true);

        ValueAxis valueAxis = new ValueAxis();
        valueAxis.splitLine().show(true); // Y轴方向显示间隔线
        valueAxis.axisTick().show(false); // Y轴上显示小标记
        LineStyle lineStyle = new LineStyle();
        lineStyle.color("#5b657c");
        valueAxis.splitLine().lineStyle(lineStyle);
        AxisLine axisLine = new AxisLine();
        axisLine.lineStyle(lineStyle);
        valueAxis.axisLine(axisLine);
        option.yAxis(valueAxis);
        List<String> legendData = new ArrayList<>();
        List<String> categoryAxisData = new ArrayList<>();
        List<HudBean> barAllData = new ArrayList<>();
        for (HudBean hb : data) {
            if (flag.equals(hb.getKeyId())) {
                barAllData.add(hb);
                if (!ConstantCommon.ChartType.CHART_TEXT.equals(hb.getKeyType())) {
                    // 生成图例数据
                    legendData.add(hb.getKeyView());
                    // 生成X轴数据
                    categoryAxisData.add(hb.getKeyName());
                } else {
                    msg.setText("\u3000\u3000" + hb.getKeyValue());
                }
            }
        }
        option.legend().data(removeDuplicateWithOrder(legendData));
        option.legend().textStyle(textStyle);
        CategoryAxis categoryAxis = new CategoryAxis();

        categoryAxis.data(removeDuplicateWithOrder(categoryAxisData).toArray());
        categoryAxis.axisLabel().setTextStyle(textStyle);
        categoryAxis.splitLine().show(false);
        categoryAxis.axisTick().show(false);
        categoryAxis.axisLine().lineStyle(lineStyle);
        option.xAxis(categoryAxis);

        List<Series> series = new ArrayList<>();
        for (String s : legendData) {
            Bar bar = new Bar(s);
            switch (flag) {
                case FLAG_LIST_ONE_CENTER:
                    bar.barWidth(18);
                    break;
                case FLAG_LIST_TWO_BOTTOM:
                    bar.barWidth(18);
                    break;
                case FLAG_LIST_THREE_NO2:
                    bar.barWidth(6);
                    break;
                case FLAG_LIST_THREE_NO4:
                    bar.barWidth(12);
                    break;
            }
            bar.barGap("20%");
            for (HudBean hb : barAllData) {
                if (s.equals(hb.getKeyView())) {
                    if (!ConstantCommon.ChartType.CHART_TEXT.equals(hb.getKeyType())) {
                        bar.data().add(Integer.parseInt(hb.getKeyValue()));
                    }
                }
            }
            series.add(bar);
        }
        option.series(series);

        switch (flag) {
            case FLAG_LIST_ONE_CENTER:
                Grid gridOneCenter = new Grid();
                gridOneCenter.setX(28);
                gridOneCenter.setY(30);
                gridOneCenter.setX2(35);
                gridOneCenter.setY2(28);
                option.grid(gridOneCenter);
                break;
            case FLAG_LIST_TWO_BOTTOM:
                Grid gridListTwoBottom = new Grid();
                gridListTwoBottom.setX(28);
                gridListTwoBottom.setY(30);
                gridListTwoBottom.setX2(25);
                gridListTwoBottom.setY2(22);
                option.grid(gridListTwoBottom);
                break;
            case FLAG_LIST_THREE_NO2:
                option.title("女干部配备情况");
                option.title().textStyle(titleStyle);
                option.legend().x("0").y("20").textStyle(textStyle);
                Grid gridListThreeNo2 = new Grid();
                gridListThreeNo2.setX(28);
                gridListThreeNo2.setY(45);
                gridListThreeNo2.setX2(25);
                gridListThreeNo2.setY2(33);
                option.grid(gridListThreeNo2);
                break;
            case FLAG_LIST_THREE_NO4:
                option.title("党外干部配备情况");
                option.title().textStyle(titleStyle);
                option.legend().x("0").y("20").textStyle(textStyle);
                Grid gridListThreeNo4 = new Grid();
                gridListThreeNo4.setX(28);
                gridListThreeNo4.setY(45);
                gridListThreeNo4.setX2(25);
                gridListThreeNo4.setY2(34);
                option.grid(gridListThreeNo4);
                break;
        }
        return option;
    }

    private GsonOption getPieOption(String flag) {
        GsonOption option = new GsonOption();

        switch (flag) {
            case FLAG_LIST_TWO_TOP:

                List<PieDataBean> pieDataBeansTwoTop = new ArrayList<>();
                List<String> keyViewsTwoTop = new ArrayList<>();

                List<String> tempBeans = new ArrayList<>();

                for (HudBean hudBean : data) {
                    if (hudBean.getKeyId().equals(FLAG_LIST_TWO_TOP) && (!hudBean.getKeyType().equals("4"))) {
                        PieDataBean pieDataBean = new PieDataBean(Integer.valueOf(hudBean.getKeyValue()), hudBean.getKeyName());
                        pieDataBeansTwoTop.add(pieDataBean);
                        keyViewsTwoTop.add(hudBean.getKeyView());
                    }

                    if (hudBean.getKeyId().equals(FLAG_LIST_TWO_TOP) && hudBean.getKeyType().equals("4")) {
                        tempBeans.add(hudBean.getKeyOrder());
                    }
                }

                for (HudBean hudBean : data) {
                    if (hudBean.getKeyId().equals(FLAG_LIST_TWO_TOP) && hudBean.getKeyOrder().equals(Collections.max(tempBeans))) {
                        ((TextView) findViewById(R.id.tv_list_two_top2)).setText("\u3000\u3000" + hudBean.getKeyValue());
                    } else if (hudBean.getKeyId().equals(FLAG_LIST_TWO_TOP) && hudBean.getKeyOrder().equals(Collections.min(tempBeans))) {
                        ((TextView) findViewById(R.id.tv_list_two_top1)).setText("\u3000\u3000" + hudBean.getKeyValue());
                    }
                }


                PieDataBean[] dataBeansTwoTop = new PieDataBean[pieDataBeansTwoTop.size()];
                String[] legendsTwoTop = new String[keyViewsTwoTop.size()];

                option.legend(keyViewsTwoTop.toArray(legendsTwoTop));

                Legend legend = new Legend();
                legend.orient(horizontal).x(10).y(5);
                option.legend(legend);
                option.legend().textStyle(textStyle).itemHeight(6).itemWidth(10);
                Pie pie = new Pie();

                pie.data(pieDataBeansTwoTop.toArray(dataBeansTwoTop));

                ItemStyle itemStyle = new ItemStyle();
                Normal normal = new Normal();
                Emphasis emphasis = new Emphasis();
                Label label = new Label();
                label.show(true).position("outer").formatter("{d}%");
                LabelLine labelLine = new LabelLine();
                labelLine.show(true);
                normal.label(label).labelLine(labelLine);
                emphasis.label(label).labelLine(labelLine);

                itemStyle.normal(normal).emphasis(emphasis);

                pie.itemStyle(itemStyle);
                pie.center("50%", "57%");
                pie.radius(70);

                option.series(pie);
                break;
            case FLAG_LIST_ONE_BOTTOM:

                List<PieDataBean> pieDataBeansOneBottom = new ArrayList<>();

                for (HudBean hudBean : data) {
                    if (hudBean.getKeyId().equals(FLAG_LIST_ONE_BOTTOM) && (!hudBean.getKeyType().equals("4"))) {
                        PieDataBean pieDataBean = new PieDataBean(Integer.valueOf(hudBean.getKeyValue()), hudBean.getKeyName());
                        pieDataBeansOneBottom.add(pieDataBean);
                    }

                    if (hudBean.getKeyId().equals(FLAG_LIST_ONE_BOTTOM) && hudBean.getKeyType().equals("4")) {
                        ((TextView) findViewById(R.id.tv_list_one_bottom_text)).setText("\u3000\u3000" + hudBean.getKeyValue());
                    }
                }

                PieDataBean[] dataBeansOneBottom = new PieDataBean[pieDataBeansOneBottom.size()];
//                String[] legendsOneBottom = new String[keyViewsOneBottom.size()];

                Pie pieOneBottom = new Pie();

                pieOneBottom.data(pieDataBeansOneBottom.toArray(dataBeansOneBottom));
                ItemStyle itemStyle1 = new ItemStyle();
                Normal normal1 = new Normal();
                Emphasis emphasis1 = new Emphasis();
                Label label1 = new Label();
                label1.show(true).position("outer").formatter("{d}%" + "\\n" + "{b}" + "{c}人");
                LabelLine labelLine1 = new LabelLine();
                labelLine1.show(false);
                if (pieDataBeansOneBottom.size() > 1) {
                    labelLine1.length(-5);
                }

                normal1.label(label1).labelLine(labelLine1);
                emphasis1.label(label1).labelLine(labelLine1);

                itemStyle1.normal(normal1).emphasis(emphasis1);
                pieOneBottom.itemStyle(itemStyle1);

                pieOneBottom.radius(45, 65);
                option.series(pieOneBottom);

                break;
        }
        return option;
    }

    /**
     * 删除ArrayList中重复元素，保持顺序
     *
     * @param list old list
     * @return new list
     */
    public List removeDuplicateWithOrder(List list) {
        Set set = new HashSet();
        List newList = new ArrayList();
        for (Iterator iter = list.iterator(); iter.hasNext(); ) {
            Object element = iter.next();
            if (set.add(element))
                newList.add(element);
        }
        list.clear();
        list.addAll(newList);
        return list;
    }
}